import { ref, computed, watch, onMounted } from "vue";
import SignaturePad from "signature_pad";
import request from "@/utils/request";

export function useSignPadHook(props: any, emit: any) {
  // 手写签名实例
  const signaturePad = ref<any>(null);
  // 画板
  const canvas = ref<any>(null);
  const signImageUrl = ref("");
  const signaturePadBoxRef = ref<any>(null);
  const config = computed(() => ({
    minWidth: 1,
    maxWidth: 3,
    penColor: props.color
  }));

  // 是否是绘制状态 否的话就是擦除状态
  const drawStatus = ref(true);

  watch(
    () => props.value,
    val => {
      signImageUrl.value = val;
    }
  );

  watch(
    () => props.backgroundImg,
    () => {
      initSignaturePad();
    }
  );

  onMounted(() => {
    signImageUrl.value = props.value;
  });

  const resizeCanvas = () => {
    console.log("resizeCanvas");
    if (!canvas.value) {
      return;
    }
    const ratio = Math.max(window.devicePixelRatio || 1, 1);
    canvas.value!.width = canvas.value?.offsetWidth * ratio;
    canvas.value!.height = canvas.value?.offsetHeight * ratio;
    canvas.value!.getContext("2d").scale(ratio, ratio);
    signaturePad.value!.clear();
  };

  const initSignaturePad = () => {
    canvas.value = signaturePadBoxRef.value;
    if (!canvas.value) {
      return;
    }
    console.log(signaturePadBoxRef.value);
    signaturePad.value = new SignaturePad(canvas.value, config.value);
    drawBgImg();
    signaturePad.value.addEventListener(
      "endStroke",
      () => {
        console.log("Signature started");
      },
      { once: true }
    );
  };

  const bgBase64Data = ref("");

  const drawBgImg = () => {
    if (!props.backgroundImg) {
      return;
    }
    convertImgToBase64(
      props.backgroundImg,
      (base64Data: string) => {
        bgBase64Data.value = base64Data;
        signaturePad.value.fromDataURL(base64Data, config.value);
      },
      "image/png"
    );
  };

  const convertImgToBase64 = (url: string, callback: Function, outputFormat: string) => {
    let canvas: HTMLCanvasElement = document.createElement("canvas");
    let ctx = canvas!.getContext("2d");
    let img = new Image();
    img.crossOrigin = "Anonymous";
    img.onload = function () {
      canvas.height = img.height;
      canvas.width = img.width;
      ctx!.drawImage(img, 0, 0);
      let dataURL = canvas.toDataURL(outputFormat || "image/png");
      callback.call(this, dataURL);
    };
    img.src = url;
  };

  const resizeMobileCanvas = () => {
    console.log("resizeCanvas");
    if (!canvas.value) {
      return;
    }
    const ratio = Math.max(window.devicePixelRatio || 1, 1);
    // This part causes the canvas to be cleared
    canvas.value.width = document.body.clientWidth - 20;
    canvas.value.height = 300;
    canvas.value.getContext("2d").scale(ratio, ratio);

    signaturePad.value.clear();
  };

  const initMobileSignaturePad = () => {
    canvas.value = signaturePadBoxRef.value;
    signaturePad.value = new SignaturePad(canvas.value, config.value);
    canvas.value.height = 300;
    canvas.value.width = document.body.clientWidth - 20;
  };

  const clear = () => {
    signaturePad.value!.clear();
  };

  const undo = () => {
    const data = signaturePad.value!.toData();
    if (props.backgroundImg) {
      signaturePad.value!.clear();
      data.pop(); // remove the last dot or line
      signaturePad.value.fromDataURL(bgBase64Data.value, config.value).then(() => {
        signaturePad.value!.fromData(data, { clear: false });
      });
    } else {
      if (data) {
        data.pop(); // remove the last dot or line
        signaturePad.value!.fromData(data);
      }
    }
  };

  const savePng = async () => {
    if (signaturePad.value!.isEmpty()) {
      console.error("请先填写");
      return;
    }
    const data = signaturePad.value!.toDataURL("image/png");
    const file = dataURLtoFile(data, `${new Date().getTime()}.png`);
    const param = new FormData();
    param.append("file", file);
    const config = {
      headers: { "Content-Type": "multipart/form-data" }
    };

    request.post(props.action, param, config).then(res => {
      signImageUrl.value = res.data;
      emit("update:value", res.data);
    });
  };

  const reSign = () => {
    signImageUrl.value = "";
    signaturePad.value.clear();
    drawBgImg();
  };

  const dataURLtoFile = (dataurl: string, filename: string) => {
    const arr = dataurl.split(",");
    const bstr = window.atob(arr[1]);
    const u8arr = new Uint8Array(bstr.length);
    for (let i = 0; i < bstr.length; i++) {
      u8arr[i] = bstr.charCodeAt(i);
    }
    return new File([u8arr], filename, { type: "image/png" });
  };

  const eraseSignPad = () => {
    signaturePad.value!.compositeOperation = "destination-out";
    drawStatus.value = false;
  };

  const drawSignPad = () => {
    signaturePad.value!.compositeOperation = "source-over";
    drawStatus.value = true;
  };

  return {
    signaturePad,
    canvas,
    signImageUrl,
    clear,
    undo,
    savePng,
    reSign,
    signaturePadBoxRef,
    initSignaturePad,
    resizeCanvas,
    resizeMobileCanvas,
    initMobileSignaturePad,
    eraseSignPad,
    drawSignPad,
    drawStatus
  };
}
